//package com.example.config.shiro;
//
//import com.example.config.CommonConstant;
//import com.example.enity.Admin;
//import com.example.service.AdminService;
//import com.example.util.JwtUtil;
//import com.example.util.RedisUtil;
//import com.example.util.oConvertUtils;
//import org.apache.shiro.authc.AuthenticationException;
//import org.apache.shiro.authc.AuthenticationInfo;
//import org.apache.shiro.authc.AuthenticationToken;
//import org.apache.shiro.authc.SimpleAuthenticationInfo;
//import org.apache.shiro.authz.AuthorizationInfo;
//import org.apache.shiro.realm.AuthorizingRealm;
//import org.apache.shiro.subject.PrincipalCollection;
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.stereotype.Component;
//
//import javax.annotation.Resource;
//
//@Component
//public class ShiroRelam extends AuthorizingRealm {
//    @Resource
//    private AdminService adminService;
//
//    @Autowired
//    private RedisUtil redisUtil;
//
//
//    /**
//     * 必须重写此方法，不然Shiro会报错
//     */
//    @Override
//    public boolean supports(AuthenticationToken token) {
//        return token instanceof JwtToken;
//    }
//
//
//    /**
//     * 授权
//     * @param principalCollection
//     * @return
//     */
//    @Override
//    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
//        return null;
//    }
//
//    /**
//     * 身份验证
//     * @param authenticationToken
//     * @return
//     * @throws AuthenticationException
//     */
//    @Override
//    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
//        String token = (String) authenticationToken.getCredentials();
//        Admin admin = checkAdminTokenIsEffect(token);
//        return new SimpleAuthenticationInfo(admin, token, getName());
//    }
//
//    /**
//     * 校验token的有效性
//     * @param token
//     */
//    public Admin checkAdminTokenIsEffect(String token) throws AuthenticationException {
//        // 解密获得username，用于和数据库进行对比
//        String username = JwtUtil.getUsername(token);
//        if (username == null) {
//            throw new AuthenticationException("token非法无效!");
//        }
//        Admin admin = adminService.getAdminByUsername(username);
//        if( admin == null ){
//            throw new AuthenticationException("用户不存在!");
//        }
//        //校验token是否超时失效 & 或者账号密码是否错误
//        if (!jwtTokenRefresh(token, username, admin.getPwd())) {
//            throw new AuthenticationException("Token失效，请重新登录!");
//        }
//        return admin;
//
//    }
//
//    /**
//     * 令牌刷新机制
//     * 1.token是否过期取决于redis中的token，而不是Jwt的token
//     * 2.当redis中的token过期后，返回false
//     * 3.当redis中的token没有过期，Jwt中的token也没有过期，返回true
//     * 4.当redis中的token没有过期，Jwt中的token
//     * @param token
//     * @param username
//     * @param pwd
//     * @return
//     */
//    private boolean jwtTokenRefresh(String token, String username, String pwd) {
//        String cacheToken = String.valueOf(redisUtil.get(CommonConstant.PREFIX_USER_TOKEN + token));
//        if (oConvertUtils.isNotEmpty(cacheToken)) {
//            // 校验token有效性:用户名、密码是否正确，token是否过期
//            //令牌刷新机制
//            if (!JwtUtil.verify(cacheToken, username, pwd)) {
//                //无效
//                //重新生成token
//                String newAuthorization = JwtUtil.sign(username, pwd);
//                // 重新设置超时时间
//                redisUtil.set(CommonConstant.PREFIX_USER_TOKEN + token, newAuthorization);
//                redisUtil.expire(CommonConstant.PREFIX_USER_TOKEN + token, JwtUtil.EXPIRE_TIME * 2 / 1000);
//            }
//            return true;
//        }
//        return false;
//    }
//
//}
